package com.logistics.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.logistics.common.Constants;
import com.logistics.common.SiteContextHolder;
import com.logistics.common.TenantContextHolder;
import com.logistics.dto.OrderCreateRequest;
import com.logistics.dto.OrderQueryRequest;
import com.logistics.entity.DispatchRecord;
import com.logistics.entity.Driver;
import com.logistics.entity.TransportOrder;
import com.logistics.entity.Vehicle;
import com.logistics.mapper.DispatchRecordMapper;
import com.logistics.mapper.DriverMapper;
import com.logistics.mapper.TransportOrderMapper;
import com.logistics.mapper.VehicleMapper;
import com.logistics.service.DispatchRecordService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 订单服务
 */
@Service
public class OrderService {
    
    private final TransportOrderMapper orderMapper;
    private final DriverMapper driverMapper;
    private final VehicleMapper vehicleMapper;
    private final DispatchRecordMapper dispatchRecordMapper;
    private final DispatchRecordService dispatchRecordService;
    private final DriverService driverService;
    
    public OrderService(TransportOrderMapper orderMapper, 
                       DriverMapper driverMapper,
                       VehicleMapper vehicleMapper,
                       DispatchRecordMapper dispatchRecordMapper,
                       DispatchRecordService dispatchRecordService,
                       DriverService driverService) {
        this.orderMapper = orderMapper;
        this.driverMapper = driverMapper;
        this.vehicleMapper = vehicleMapper;
        this.dispatchRecordMapper = dispatchRecordMapper;
        this.dispatchRecordService = dispatchRecordService;
        this.driverService = driverService;
    }
    
    /**
     * 创建订单（收货开票）
     */
    public TransportOrder createOrder(OrderCreateRequest request, Long userId, String issuerName) {
        Long tenantId = TenantContextHolder.getTenantId();
        
        // 生成订单编号
        String orderNo = generateOrderNo(tenantId);
        
        // 构建订单对象
        TransportOrder order = new TransportOrder();
        order.setTenantId(tenantId);
        order.setSiteId(request.getSiteId());
        order.setOrderNo(orderNo);
        order.setGoodsCode(request.getGoodsCode());
        
        // 站点信息
        order.setDepartureSiteId(request.getDepartureSiteId());
        order.setDepartureSiteName(request.getDepartureSiteName());
        order.setArrivalSiteId(request.getArrivalSiteId());
        order.setArrivalSiteName(request.getArrivalSiteName());
        
        // 发货信息
        order.setSenderName(request.getSenderName());
        order.setSenderPhone(request.getSenderPhone());
        
        // 收货信息
        order.setReceiverName(request.getReceiverName());
        order.setReceiverPhone(request.getReceiverPhone());
        order.setDeliveryType(request.getDeliveryType());
        order.setDeliveryOptions(request.getDeliveryOptions());
        order.setReceiverAddress(request.getReceiverAddress());
        
        // 货物信息
        order.setGoodsName(request.getGoodsName());
        order.setGoodsPackage(request.getGoodsPackage());
        order.setGoodsPieces(request.getGoodsPieces());
        
        // 运费信息
        order.setFreightAmount(request.getFreightAmount());  // 实收运费
        order.setSettlementAmount(request.getSettlementAmount());  // 结算运费
        order.setCollectionAmount(request.getCollectionAmount());
        order.setPaymentMethod(request.getPaymentMethod());
        
        // 司机设置（可选）
        // 车辆分配留到后续运单装车功能
        if (request.getDriverId() != null) {
            Driver driver = driverMapper.selectById(request.getDriverId());
            if (driver != null) {
                order.setDriverId(driver.getId());
                order.setDriverName(driver.getName());
            }
        }
        
        // 订单状态：已收货（开票即收货）
        order.setOrderStatus(Constants.OrderStatus.RECEIVED);
        
        // 开票员信息（自动填充为当前用户）
        order.setIssuerId(userId);
        order.setIssuerName(issuerName);
        
        order.setRemark(request.getRemark());
        order.setCreateBy(userId);
        
        orderMapper.insert(order);
        
        return order;
    }
    
    /**
     * 分页查询订单列表（支持全字段查询）
     */
    public IPage<TransportOrder> getOrderList(OrderQueryRequest request) {
        Page<TransportOrder> page = new Page<>(request.getCurrent(), request.getSize());
        
        LambdaQueryWrapper<TransportOrder> wrapper = new LambdaQueryWrapper<>();
        
        // 租户隔离
        Long tenantId = TenantContextHolder.getTenantId();
        wrapper.eq(TransportOrder::getTenantId, tenantId);
        
        // 订单状态筛选
        if (StringUtils.hasText(request.getOrderStatus())) {
            wrapper.eq(TransportOrder::getOrderStatus, request.getOrderStatus());
        }
        
        // 订单编号筛选
        if (StringUtils.hasText(request.getOrderNo())) {
            wrapper.like(TransportOrder::getOrderNo, request.getOrderNo());
        }
        
        // 货物编码筛选
        if (StringUtils.hasText(request.getGoodsCode())) {
            wrapper.like(TransportOrder::getGoodsCode, request.getGoodsCode());
        }
        
        // 站点筛选
        if (request.getDepartureSiteId() != null) {
            wrapper.eq(TransportOrder::getDepartureSiteId, request.getDepartureSiteId());
        }
        if (request.getArrivalSiteId() != null) {
            wrapper.eq(TransportOrder::getArrivalSiteId, request.getArrivalSiteId());
        }
        
        // 司机筛选
        if (request.getDriverId() != null) {
            wrapper.eq(TransportOrder::getDriverId, request.getDriverId());
        }
        
        // 车辆筛选
        if (request.getVehicleId() != null) {
            wrapper.eq(TransportOrder::getVehicleId, request.getVehicleId());
        }
        
        // 付款方式筛选
        if (StringUtils.hasText(request.getPaymentMethod())) {
            wrapper.eq(TransportOrder::getPaymentMethod, request.getPaymentMethod());
        }
        
        // 时间范围筛选（创建时间）
        if (request.getStartTime() != null) {
            wrapper.ge(TransportOrder::getCreateTime, request.getStartTime());
        }
        if (request.getEndTime() != null) {
            wrapper.le(TransportOrder::getCreateTime, request.getEndTime());
        }

        // 装车时间范围筛选（如提供）
        if (request.getLoadedAtStart() != null) {
            wrapper.ge(TransportOrder::getLoadedAt, request.getLoadedAtStart());
        }
        if (request.getLoadedAtEnd() != null) {
            wrapper.le(TransportOrder::getLoadedAt, request.getLoadedAtEnd());
        }
        
        // 关键词搜索（全字段模糊查询）
        if (StringUtils.hasText(request.getKeyword())) {
            wrapper.and(w -> w
                .like(TransportOrder::getOrderNo, request.getKeyword())
                .or().like(TransportOrder::getGoodsCode, request.getKeyword())
                .or().like(TransportOrder::getSenderName, request.getKeyword())
                .or().like(TransportOrder::getSenderPhone, request.getKeyword())
                .or().like(TransportOrder::getReceiverName, request.getKeyword())
                .or().like(TransportOrder::getReceiverPhone, request.getKeyword())
                .or().like(TransportOrder::getGoodsName, request.getKeyword())
                .or().like(TransportOrder::getDriverName, request.getKeyword())
                .or().like(TransportOrder::getVehiclePlate, request.getKeyword())
                .or().like(TransportOrder::getIssuerName, request.getKeyword())
            );
        }
        
        // 精确字段搜索
        if (StringUtils.hasText(request.getSenderName())) {
            wrapper.like(TransportOrder::getSenderName, request.getSenderName());
        }
        
        if (StringUtils.hasText(request.getReceiverName())) {
            wrapper.like(TransportOrder::getReceiverName, request.getReceiverName());
        }
        
        if (StringUtils.hasText(request.getSenderPhone())) {
            wrapper.like(TransportOrder::getSenderPhone, request.getSenderPhone());
        }
        
        if (StringUtils.hasText(request.getReceiverPhone())) {
            wrapper.like(TransportOrder::getReceiverPhone, request.getReceiverPhone());
        }
        
        if (StringUtils.hasText(request.getGoodsName())) {
            wrapper.like(TransportOrder::getGoodsName, request.getGoodsName());
        }
        
        if (StringUtils.hasText(request.getDriverName())) {
            wrapper.like(TransportOrder::getDriverName, request.getDriverName());
        }
        
        if (StringUtils.hasText(request.getDriverPhone())) {
            wrapper.like(TransportOrder::getDriverPhone, request.getDriverPhone());
        }
        
        if (StringUtils.hasText(request.getVehiclePlate())) {
            wrapper.like(TransportOrder::getVehiclePlate, request.getVehiclePlate());
        }
        
        if (StringUtils.hasText(request.getIssuerName())) {
            wrapper.like(TransportOrder::getIssuerName, request.getIssuerName());
        }
        
        // 开票员ID筛选
        if (request.getIssuerId() != null) {
            wrapper.eq(TransportOrder::getIssuerId, request.getIssuerId());
        }
        
        // 按创建时间倒序
        wrapper.orderByDesc(TransportOrder::getCreateTime);
        
        IPage<TransportOrder> result = orderMapper.selectPage(page, wrapper);
        
        // 根据用户角色和查询参数判断是否隐藏实收运费
        // 业务规则：
        // 1. 收货开票页面（查询 departureSiteId）：发货站点查看自己的订单，总是显示实收运费和结算运费
        // 2. 到货中心页面（查询 arrivalSiteId）：到货站点查看到货订单
        //    - 超级管理员 + 全部站点（arrivalSiteId=null）：显示实收运费和结算运费
        //    - 其他情况：只显示结算运费
        String role = getCurrentUserRole();
        boolean isArrivalQuery = request.getArrivalSiteId() != null;  // 到货中心页面查询了具体站点
        
        // 判断是否需要隐藏实收运费
        // 条件：到货中心页面 && (不是超级管理员 || 查询了具体站点)
        boolean shouldHideFreightAmount = isArrivalQuery && 
            (!Constants.Role.SUPER_ADMIN.equals(role) || isArrivalQuery);
        
        if (shouldHideFreightAmount) {
            // 隐藏实收运费
            result.getRecords().forEach(order -> {
                order.setFreightAmount(null);
            });
        }
        
        return result;
    }
    
    /**
     * 获取订单详情
     */
    public TransportOrder getOrderById(Long id) {
        TransportOrder order = orderMapper.selectById(id);
        
        if (order != null) {
            // 根据用户角色和站点权限，隐藏实收运费字段
            String role = getCurrentUserRole();
            Long currentSiteId = SiteContextHolder.getSiteId();
            boolean isViewingAllSites = Constants.Role.SUPER_ADMIN.equals(role) && currentSiteId == null;
            
            if (!isViewingAllSites) {
                // 非超级管理员或超级管理员选择了具体站点，隐藏实收运费
                order.setFreightAmount(null);
            }
        }
        
        return order;
    }
    
    /**
     * 更新订单
     */
    public void updateOrder(Long id, com.logistics.dto.OrderUpdateRequest request) {
        TransportOrder order = orderMapper.selectById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查订单状态
        if ("COMPLETED".equals(order.getOrderStatus()) || "CANCELLED".equals(order.getOrderStatus())) {
            throw new RuntimeException("已完成或已取消的订单不可编辑");
        }
        
        // 根据状态限制可编辑字段
        if ("TRANSPORTING".equals(order.getOrderStatus())) {
            // 运输中只能修改收货信息和备注
            if (request.getReceiverName() != null) order.setReceiverName(request.getReceiverName());
            if (request.getReceiverPhone() != null) order.setReceiverPhone(request.getReceiverPhone());
            if (request.getDeliveryType() != null) order.setDeliveryType(request.getDeliveryType());
            if (request.getDeliveryOptions() != null) order.setDeliveryOptions(request.getDeliveryOptions());
            if (request.getReceiverAddress() != null) order.setReceiverAddress(request.getReceiverAddress());
            // 备注字段：允许设置空字符串来清空
            if (request.getRemark() != null) {
                if (request.getRemark().isEmpty()) {
                    // 使用UpdateWrapper强制更新为null
                    UpdateWrapper<TransportOrder> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", id);
                    updateWrapper.set("remark", null);
                    orderMapper.update(null, updateWrapper);
                    order.setRemark(null);
                } else {
                    order.setRemark(request.getRemark());
                }
            }
        } else {
            // 待分配和已分配可编辑大部分字段
            if (request.getGoodsCode() != null) order.setGoodsCode(request.getGoodsCode());
            if (request.getDepartureSiteId() != null) order.setDepartureSiteId(request.getDepartureSiteId());
            if (request.getDepartureSiteName() != null) order.setDepartureSiteName(request.getDepartureSiteName());
            if (request.getArrivalSiteId() != null) order.setArrivalSiteId(request.getArrivalSiteId());
            if (request.getArrivalSiteName() != null) order.setArrivalSiteName(request.getArrivalSiteName());
            if (request.getSenderName() != null) order.setSenderName(request.getSenderName());
            if (request.getSenderPhone() != null) order.setSenderPhone(request.getSenderPhone());
            if (request.getReceiverName() != null) order.setReceiverName(request.getReceiverName());
            if (request.getReceiverPhone() != null) order.setReceiverPhone(request.getReceiverPhone());
            if (request.getDeliveryType() != null) order.setDeliveryType(request.getDeliveryType());
            if (request.getDeliveryOptions() != null) order.setDeliveryOptions(request.getDeliveryOptions());
            if (request.getReceiverAddress() != null) order.setReceiverAddress(request.getReceiverAddress());
            if (request.getGoodsName() != null) order.setGoodsName(request.getGoodsName());
            if (request.getGoodsPackage() != null) order.setGoodsPackage(request.getGoodsPackage());
            if (request.getGoodsPieces() != null) order.setGoodsPieces(request.getGoodsPieces());
            if (request.getFreightAmount() != null) order.setFreightAmount(request.getFreightAmount());
            if (request.getSettlementAmount() != null) order.setSettlementAmount(request.getSettlementAmount());
            if (request.getCollectionAmount() != null) order.setCollectionAmount(request.getCollectionAmount());
            if (request.getPaymentMethod() != null) order.setPaymentMethod(request.getPaymentMethod());
            
            // 司机更新（已解除绑定关系）
            if (request.getDriverId() != null) {
                Driver driver = driverMapper.selectById(request.getDriverId());
                if (driver != null) {
                    order.setDriverId(driver.getId());
                    order.setDriverName(driver.getName());
                }
            }
            
            // 备注字段：允许设置空字符串来清空
            if (request.getRemark() != null) {
                if (request.getRemark().isEmpty()) {
                    // 使用UpdateWrapper强制更新为null
                    UpdateWrapper<TransportOrder> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", id);
                    updateWrapper.set("remark", null);
                    orderMapper.update(null, updateWrapper);
                    order.setRemark(null);
                } else {
                    order.setRemark(request.getRemark());
                }
            }
        }
        
        orderMapper.updateById(order);
    }

    /**
     * 批量装车
     */
    public java.util.Map<String, Object> loadOrders(com.logistics.dto.OrderLoadRequest request) {
        if (request.getIds() == null || request.getIds().isEmpty()) {
            throw new RuntimeException("请选择要装车的订单");
        }
        if ((request.getVehicleId() == null || request.getVehicleId() <= 0) && !org.springframework.util.StringUtils.hasText(request.getVehicleNo())) {
            throw new RuntimeException("请先选择公司车辆或填写临时车辆");
        }

        java.util.List<TransportOrder> orders = orderMapper.selectBatchIds(request.getIds());
        if (orders == null || orders.isEmpty()) {
            throw new RuntimeException("未找到订单");
        }

        // 统一校验：同一发货站点+同一道货站点
        Long dep = null, arr = null;
        for (TransportOrder o : orders) {
            if (dep == null) { dep = o.getDepartureSiteId(); }
            if (arr == null) { arr = o.getArrivalSiteId(); }
            if (!java.util.Objects.equals(dep, o.getDepartureSiteId()) || !java.util.Objects.equals(arr, o.getArrivalSiteId())) {
                throw new RuntimeException("批量装车要求同一发货站点且同一道货站点");
            }
        }

        // 站点范围校验
        String role = getCurrentUserRole();
        Long currentSiteId = SiteContextHolder.getSiteId();
        boolean isSuperAllSites = (Constants.Role.SUPER_ADMIN.equals(role) && currentSiteId == null);
        if (!isSuperAllSites) {
            if (currentSiteId == null) {
                throw new RuntimeException("请先选择站点后再装车");
            }
            if (!java.util.Objects.equals(currentSiteId, dep)) {
                throw new RuntimeException("只能在当前站点进行装车");
            }
        }

        // 车辆信息
        Vehicle vehicle = null;
        Long tenantId = TenantContextHolder.getTenantId();
        if (request.getVehicleId() != null && request.getVehicleId() > 0) {
            vehicle = vehicleMapper.selectById(request.getVehicleId());
            if (vehicle == null) {
                throw new RuntimeException("车辆不存在");
            }
            if (vehicle.getTenantId() != null && !vehicle.getTenantId().equals(tenantId)) {
                throw new RuntimeException("车辆不属于当前租户");
            }
            
            // 检查车辆路线一致性：查询该车辆是否已有待发车或已发车的记录
            LambdaQueryWrapper<DispatchRecord> dispatchWrapper = new LambdaQueryWrapper<>();
            dispatchWrapper.eq(DispatchRecord::getVehicleId, vehicle.getId())
                          .eq(DispatchRecord::getTenantId, tenantId)
                          .in(DispatchRecord::getDispatchStatus, "READY", "DISPATCHED")  // 待发车或已发车状态
                          .orderByDesc(DispatchRecord::getCreateTime)
                          .last("LIMIT 1");
            DispatchRecord existingDispatch = dispatchRecordMapper.selectOne(dispatchWrapper);
            
            if (existingDispatch != null) {
                // 车辆已有路线，检查当前货物的始发站和目的地是否一致
                if (!java.util.Objects.equals(existingDispatch.getDepartureSiteId(), dep)) {
                    throw new RuntimeException("该车辆已装载其他路线的货物，始发站不一致（车辆路线：" 
                        + existingDispatch.getDepartureSiteName() + " → " + existingDispatch.getArrivalSiteName() + "）");
                }
                if (!java.util.Objects.equals(existingDispatch.getArrivalSiteId(), arr)) {
                    throw new RuntimeException("该车辆已装载其他路线的货物，目的地不一致（车辆路线：" 
                        + existingDispatch.getDepartureSiteName() + " → " + existingDispatch.getArrivalSiteName() + "）");
                }
            }
        } else if (org.springframework.util.StringUtils.hasText(request.getVehicleNo())) {
            // 临时车辆：按车牌在车辆档案中查找或自动创建
            LambdaQueryWrapper<Vehicle> vehicleWrapper = new LambdaQueryWrapper<>();
            vehicleWrapper.eq(Vehicle::getTenantId, tenantId)
                    .eq(Vehicle::getPlateNumber, request.getVehicleNo());
            vehicle = vehicleMapper.selectOne(vehicleWrapper);
            if (vehicle == null) {
                vehicle = new Vehicle();
                vehicle.setTenantId(tenantId);
                vehicle.setPlateNumber(request.getVehicleNo());
                vehicle.setVehicleType("TRUCK"); // 临时车辆默认为货车，可后续在车辆管理中修改
                vehicle.setVehicleStatus("AVAILABLE");
                vehicle.setVehicleSource("TEMP");
                // 临时车主信息可以后续在车辆管理中补全，这里尽量用装车时的司机信息占位
                String ownerName = request.getDriverName();
                String ownerPhone = request.getDriverPhone();
                if (!org.springframework.util.StringUtils.hasText(ownerName)) {
                    ownerName = "待补充";
                }
                if (!org.springframework.util.StringUtils.hasText(ownerPhone)) {
                    ownerPhone = "待补充";
                }
                vehicle.setOwnerName(ownerName);
                vehicle.setOwnerPhone(ownerPhone);
                // 载重、保险到期、年检到期允许为空，由后续人工补充
                vehicleMapper.insert(vehicle);
            }
        }

        int success = 0, skipped = 0;
        java.util.List<Long> failedIds = new java.util.ArrayList<>();
        LocalDateTime loadedAt = request.getLoadedAt() != null ? request.getLoadedAt() : LocalDateTime.now();
        for (TransportOrder o : orders) {
            if (!Constants.OrderStatus.RECEIVED.equals(o.getOrderStatus())) {
                skipped++;
                continue;
            }
            try {
                o.setOrderStatus(Constants.OrderStatus.LOADED);
                o.setLoadedAt(loadedAt);
                if (vehicle != null) {
                    o.setVehicleId(vehicle.getId());
                    o.setVehiclePlate(vehicle.getPlateNumber());
                } else {
                    // 回退逻辑：仍按旧方式仅记录车牌
                    o.setVehicleId(null);
                    o.setVehiclePlate(request.getVehicleNo());
                }
                orderMapper.updateById(o);

                // 更新车辆状态为使用中（如果是公司车辆）
                if (vehicle != null) {
                    if (!"IN_USE".equals(vehicle.getVehicleStatus())) {
                        vehicle.setVehicleStatus("IN_USE");
                        vehicleMapper.updateById(vehicle);
                    }
                }
                success++;
            } catch (Exception ex) {
                failedIds.add(o.getId());
            }
        }

        // 装车成功后，自动创建发车记录
        if (success > 0) {
            try {
                TransportOrder firstOrder = orders.get(0);
                Long departureSiteId = firstOrder.getDepartureSiteId();
                String departureSiteName = firstOrder.getDepartureSiteName();
                Long arrivalSiteId = firstOrder.getArrivalSiteId();
                String arrivalSiteName = firstOrder.getArrivalSiteName();
                String remark = request.getRemark();
                
                if (vehicle != null) {
                    // 正式车辆
                    String finalRemark = org.springframework.util.StringUtils.hasText(remark) ? remark : "装车后自动创建";
                    dispatchRecordService.createDispatch(vehicle.getId(), departureSiteId, departureSiteName, 
                        arrivalSiteId, arrivalSiteName, finalRemark);
                } else {
                    // 临时车辆
                    String tempRemark = org.springframework.util.StringUtils.hasText(remark) ? remark : "临时车辆装车后自动创建";
                    dispatchRecordService.createTempDispatch(
                        request.getVehicleNo(),
                        "TEMP", // 临时车辆类型
                        departureSiteId,
                        departureSiteName,
                        arrivalSiteId,
                        arrivalSiteName,
                        request.getDriverName(),
                        request.getDriverPhone(),
                        tempRemark
                    );
                }
            } catch (Exception e) {
                // 发车记录创建失败不影响装车结果，只记录日志
                System.err.println("自动创建发车记录失败: " + e.getMessage());
            }
        }

        java.util.Map<String, Object> res = new java.util.HashMap<>();
        res.put("success", success);
        res.put("skipped", skipped);
        res.put("failed", failedIds);
        return res;
    }

    /**
     * 批量卸车
     */
    public java.util.Map<String, Object> unloadOrders(java.util.List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要卸车的订单");
        }
        java.util.List<TransportOrder> orders = orderMapper.selectBatchIds(ids);
        if (orders == null || orders.isEmpty()) {
            throw new RuntimeException("未找到订单");
        }

        // 收集需要更新订单数量的车辆ID
        java.util.Set<Long> affectedVehicleIds = new java.util.HashSet<>();
        java.util.Set<String> affectedPlates = new java.util.HashSet<>();
        
        int success = 0, skipped = 0;
        java.util.List<Long> failedIds = new java.util.ArrayList<>();
        for (TransportOrder o : orders) {
            if (!Constants.OrderStatus.LOADED.equals(o.getOrderStatus())) {
                skipped++;
                continue;
            }
            try {
                // 记录车辆信息，用于后续更新发车记录
                if (o.getVehicleId() != null) {
                    affectedVehicleIds.add(o.getVehicleId());
                }
                if (o.getVehiclePlate() != null) {
                    affectedPlates.add(o.getVehiclePlate());
                }
                
                UpdateWrapper<TransportOrder> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", o.getId());
                updateWrapper.set("order_status", Constants.OrderStatus.RECEIVED);
                updateWrapper.set("loaded_at", null);
                // 卸车后清空车辆信息（运输车辆信息不保留）
                updateWrapper.set("vehicle_id", null);
                updateWrapper.set("vehicle_plate", null);
                orderMapper.update(null, updateWrapper);

                o.setOrderStatus(Constants.OrderStatus.RECEIVED);
                o.setLoadedAt(null);
                o.setVehicleId(null);
                o.setVehiclePlate(null);
                // 注意：driverId/driverName/driverPhone 是收货司机，不在卸车时清空
                success++;
            } catch (Exception ex) {
                failedIds.add(o.getId());
            }
        }
        
        // 更新发车记录的订单数量
        Long tenantId = TenantContextHolder.getTenantId();
        for (Long vehicleId : affectedVehicleIds) {
            updateDispatchRecordOrderCount(vehicleId, null, tenantId);
        }
        for (String plate : affectedPlates) {
            updateDispatchRecordOrderCount(null, plate, tenantId);
        }

        java.util.Map<String, Object> res = new java.util.HashMap<>();
        res.put("success", success);
        res.put("skipped", skipped);
        res.put("failed", failedIds);
        return res;
    }
    
    /**
     * 更新发车记录的订单数量
     */
    private void updateDispatchRecordOrderCount(Long vehicleId, String vehiclePlate, Long tenantId) {
        try {
            // 查询该车辆待发车或已发车的记录
            LambdaQueryWrapper<DispatchRecord> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DispatchRecord::getTenantId, tenantId)
                  .in(DispatchRecord::getDispatchStatus, "READY", "DISPATCHED");
            
            if (vehicleId != null) {
                wrapper.eq(DispatchRecord::getVehicleId, vehicleId);
            } else if (vehiclePlate != null) {
                wrapper.eq(DispatchRecord::getVehiclePlate, vehiclePlate);
            } else {
                return;
            }
            
            DispatchRecord dispatch = dispatchRecordMapper.selectOne(wrapper);
            if (dispatch != null) {
                // 统计该车辆当前装载的订单数量
                Integer orderCount;
                if (vehicleId != null) {
                    orderCount = orderMapper.countByVehicleId(vehicleId, tenantId);
                } else {
                    orderCount = orderMapper.countByPlateNumber(vehiclePlate, tenantId);
                }
                
                if (orderCount == null) {
                    orderCount = 0;
                }
                
                dispatch.setOrderCount(orderCount);
                dispatchRecordMapper.updateById(dispatch);
            }
        } catch (Exception e) {
            // 更新发车记录失败不影响卸车操作
            System.err.println("更新发车记录订单数量失败: " + e.getMessage());
        }
    }
    
    /**
     * 取消订单
     */
    public void cancelOrder(Long id, String cancelReason) {
        TransportOrder order = orderMapper.selectById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查状态
        if ("IN_TRANSIT".equals(order.getOrderStatus())) {
            throw new RuntimeException("运输中的订单不可取消");
        }
        if ("COMPLETED".equals(order.getOrderStatus()) || "CANCELLED".equals(order.getOrderStatus())) {
            throw new RuntimeException("已完成或已取消的订单不可取消");
        }
        
        // 更新订单状态
        order.setOrderStatus(Constants.OrderStatus.CANCELLED);
        order.setCancelReason(cancelReason);
        order.setCancelTime(LocalDateTime.now());
        orderMapper.updateById(order);
        
        // 如果已分配，释放司机和车辆资源
        releaseResources(order);
    }
    
    /**
     * 删除订单
     */
    public void deleteOrder(Long id) {
        TransportOrder order = orderMapper.selectById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 只能删除已取消的订单
        if (!"CANCELLED".equals(order.getOrderStatus())) {
            throw new RuntimeException("只能删除已取消的订单");
        }
        
        orderMapper.deleteById(id);
    }
    
    /**
     * 更新订单状态
     */
    public void updateOrderStatus(Long id, String newStatus) {
        TransportOrder order = orderMapper.selectById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 验证状态流转
        String currentStatus = order.getOrderStatus();
        
        // 状态流转：RECEIVED → LOADED → TRANSPORTING → ARRIVED → DELIVERING → COMPLETED
        if ("RECEIVED".equals(currentStatus) && "LOADED".equals(newStatus)) {
            // 已收货 → 已装车（通常由装车接口处理）
            order.setOrderStatus(newStatus);
        } else if ("LOADED".equals(currentStatus) && "TRANSPORTING".equals(newStatus)) {
            // 已装车 → 运输中
            order.setOrderStatus(newStatus);
        } else if ("TRANSPORTING".equals(currentStatus) && "ARRIVED".equals(newStatus)) {
            // 运输中 → 到货
            order.setOrderStatus(newStatus);
        } else if ("ARRIVED".equals(currentStatus) && "DELIVERING".equals(newStatus)) {
            // 到货 → 派送中/待取货
            order.setOrderStatus(newStatus);
        } else if ("DELIVERING".equals(currentStatus) && "COMPLETED".equals(newStatus)) {
            // 派送中/待取货 → 已完成
            order.setOrderStatus(newStatus);
            order.setDeliveryTime(LocalDateTime.now());
            // 释放司机和车辆资源
            releaseResources(order);
        } else {
            throw new RuntimeException("不支持的状态流转：" + currentStatus + " → " + newStatus);
        }
        
        orderMapper.updateById(order);
    }
    
    /**
     * 分配订单（只分配司机，用于取货）
     * 车辆分配留到后续运单装车功能
     * 支持修改已分配订单的司机
     */
    public void assignOrder(Long orderId, Long driverId, String remark) {
        TransportOrder order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 允许在已收货状态分配/修改司机
        if (!Constants.OrderStatus.RECEIVED.equals(order.getOrderStatus())) {
            throw new RuntimeException("只能在已收货状态分配/修改司机");
        }
        
        // 查询新司机
        Driver newDriver = driverMapper.selectById(driverId);
        if (newDriver == null) {
            throw new RuntimeException("司机不存在");
        }
        
        // 验证司机必须是当前站点的
        Long currentSiteId = SiteContextHolder.getSiteId();
        if (currentSiteId == null || !currentSiteId.equals(newDriver.getSiteId())) {
            throw new RuntimeException("只能分配当前站点的司机");
        }
        
        // 如果选择的是同一个司机，直接返回成功
        if (order.getDriverId() != null && order.getDriverId().equals(driverId)) {
            return;
        }
        
        // 验证新司机必须是空闲状态
        if (!Constants.DriverStatus.IDLE.equals(newDriver.getDriverStatus())) {
            throw new RuntimeException("司机不是空闲状态，无法分配");
        }
        
        // 如果是修改司机，先释放原司机
        if (order.getDriverId() != null) {
            Driver oldDriver = driverMapper.selectById(order.getDriverId());
            if (oldDriver != null) {
                oldDriver.setDriverStatus(Constants.DriverStatus.IDLE);
                driverMapper.updateById(oldDriver);
            }
        }
        
        // 更新订单（只分配司机，不分配车辆）
        order.setDriverId(driverId);
        order.setDriverName(newDriver.getName());
        order.setDriverPhone(newDriver.getPhone());
        // 车辆分配留到后续运单装车功能，这里不设置vehicleId和vehiclePlate
        // 分配司机后订单仍保持RECEIVED状态，直到装车完成才变为LOADED
        order.setAssignTime(LocalDateTime.now());
        // 注意：分配备注参数保留用于未来扩展，但不写入订单备注字段
        orderMapper.updateById(order);
        
        // 设置司机状态为收货中（被收货开票订单分配）
        newDriver.setDriverStatus(Constants.DriverStatus.PICKING);
        driverMapper.updateById(newDriver);
    }
    
    /**
     * 分配/修改送货司机（用于送货上门的订单）
     */
    public void assignDeliveryDriver(Long orderId, Long deliveryDriverId) {
        TransportOrder order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查订单状态，只有已到站或配送中的订单才能分配/修改送货司机
        if (!"ARRIVED".equals(order.getOrderStatus()) && !"DELIVERING".equals(order.getOrderStatus())) {
            throw new RuntimeException("只有已到站或配送中的订单才能分配送货司机");
        }
        
        // 检查配送方式，只有送货上门的订单才需要分配送货司机
        if (!"DELIVERY".equals(order.getDeliveryType())) {
            throw new RuntimeException("只有送货上门的订单才需要分配送货司机");
        }
        
        // 查询送货司机信息
        Driver deliveryDriver = driverMapper.selectById(deliveryDriverId);
        if (deliveryDriver == null) {
            throw new RuntimeException("送货司机不存在");
        }
        
        // 分配送货司机
        order.setDeliveryDriverId(deliveryDriver.getId());
        order.setDeliveryDriverName(deliveryDriver.getName());
        order.setDeliveryDriverPhone(deliveryDriver.getPhone());
        
        // 如果是已到站状态，更新为配送中；如果已经是配送中，保持不变
        if ("ARRIVED".equals(order.getOrderStatus())) {
            order.setOrderStatus(Constants.OrderStatus.DELIVERING);
        }
        
        orderMapper.updateById(order);
    }
    
    /**
     * 取消送货（清除送货司机信息，订单状态恢复为已到站）
     */
    public void cancelDelivery(Long orderId) {
        TransportOrder order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查订单状态，只有配送中的订单才能取消送货
        if (!"DELIVERING".equals(order.getOrderStatus())) {
            throw new RuntimeException("只有配送中的订单才能取消送货");
        }
        
        // 检查配送方式
        if (!"DELIVERY".equals(order.getDeliveryType())) {
            throw new RuntimeException("只有送货上门的订单才能取消送货");
        }
        
        // 清除送货司机信息
        order.setDeliveryDriverId(null);
        order.setDeliveryDriverName(null);
        order.setDeliveryDriverPhone(null);
        
        // 订单状态恢复为已到站
        order.setOrderStatus(Constants.OrderStatus.ARRIVED);
        
        orderMapper.updateById(order);
    }
    
    /**
     * 释放司机和车辆资源（取消或完成订单时调用）
     */
    private void releaseResources(TransportOrder order) {
        // 根据司机的订单情况智能更新司机状态
        if (order.getDriverId() != null) {
            driverService.updateDriverStatusByOrders(order.getDriverId());
        }
        
        // 释放车辆
        if (order.getVehicleId() != null) {
            Vehicle vehicle = vehicleMapper.selectById(order.getVehicleId());
            if (vehicle != null && "IN_USE".equals(vehicle.getVehicleStatus())) {
                vehicle.setVehicleStatus("AVAILABLE");
                vehicleMapper.updateById(vehicle);
            }
        }
    }
    
    /**
     * 生成订单编号
     * 格式：租户前缀 + 日期 + 流水号
     */
    private String generateOrderNo(Long tenantId) {
        // 简化版：TS + 日期 + 6位随机数
        String datePart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String randomPart = String.format("%06d", (int)(Math.random() * 1000000));
        return "TS" + datePart + randomPart;
    }
    
    /**
     * 获取当前用户角色
     */
    private String getCurrentUserRole() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                Object roleObj = request.getAttribute("role");
                if (roleObj != null) {
                    return roleObj.toString();
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null;
    }
}

